Amazon FSx for Lustreにファイル読み書きしてLustreの特性を学ぶ
Lustreファイルシステムの特性を学ぶ
- Amazon FSx for LustreにAWS ParallelClusterからアクセスしてLustreの扱いを学びます
- AWS ParallelClusterはAWSがサポートするHPCクラスターの管理ツールです
- Workshopsから脱線してFSx for Lustreのストライピングした検証記録
AWS HPC WorkShops
AWS HPC Workshopsを下記の項を参考にすすめていきます。 Build a High-Performance File Systemでは、FSx for LustreをParallelClusterにマウントしてファイルのアクセス方法などが解説されています。
S3にサンプルデータのアップロード
S3に保存したデータをFSx for Lustre経由してアクセスするための準備
- S3バケット作成
- サンプルファイルをローカルにダウンロード
- サンプルファイルをS3バケットにアップロード
- ローカルのサンプルファイルを削除
> aws s3 mb s3://parallelcluster-lustre-ohmura make_bucket: parallelcluster-lustre-ohmura > wget http://s3.amazonaws.com/open.source.geoscience/open_data/seg_eage_salt/SEG_C3NA_Velocity.sgy > wget ftp://math.nist.gov/pub/MatrixMarket2/misc/cylshell/s3dkq4m2.mtx.gz > aws s3 cp SEG_C3NA_Velocity.sgy s3://parallelcluster-lustre-ohmura > aws s3 cp s3dkq4m2.mtx.gz s3://parallelcluster-lustre-ohmura > rm SEG_C3NA_Velocity.sgy > rm s3dkq4m2.mtx.gz
FSx for LustreをマウントしたParallelClusterの構築
ParallelClusterの設定ファイルでFSx for Lustreを新規作成しマウントします。
デプロイタイプは3種類あります。
- SCRATCH_1(デフォルト)
- SCRATCH_2
- データの TB ごとに 1200 MB/s のスループットにバーストできる第2世代のスクラッチファイルシステム
- PERSISTENT_1
- 高可用性の長期のストレージ向け永続ファイルシステム
FSx for Lustreのデプロイタイプはスクラッチ2を指定して作成します。
Amazon FSx for Lustre の最新情報: 長期間、高パフォーマンスワークロード用の永続ストレージ | Amazon Web Services ブログ
AWS ParallelClusterの設定ファイル
6行追加するだけでクラスター構築と同時にFSx for Lustreも新規作成・マウントしてくれます。
[fsx] section - AWS ParallelCluster
[aws] aws_region_name = us-east-1 [global] cluster_template = default update_check = true sanity_check = true [aliases] ssh = ssh {CFN_USER}@{MASTER_IP} {ARGS} [cluster default] key_name = sandbox-key-useast1 base_os = alinux2 scheduler = slurm vpc_settings = custom # Instance Type master_instance_type = c6g.large compute_instance_type = c6g.16xlarge # Use Spot Instance cluster_type = spot # Use Placemant Group placement = compute placement_group = DYNAMIC # Cluster Size maintain_initial_size = false initial_queue_size = 0 max_queue_size = 16 # Enable EBS Setting ebs_settings = external_ebs # Enable FSx Settings fsx_settings = external_fsx # Enable CloudWatchLogs cw_log_settings = cluster_log [vpc custom] # VPC Setting vpc_id = vpc-07edfc27679c9ca80 master_subnet_id = subnet-0ab2754446b2f87a4 compute_subnet_id = subnet-0ab2754446b2f87a4 use_public_ips = true [cw_log cluster_log] # CloudWatchLogs Setting enable = true retention_days = 7 [ebs external_ebs] # EBS Setting shared_dir = /shared volume_type = gp2 volume_size = 20 [fsx external_fsx] shared_dir = /lustre storage_capacity = 1200 import_path = s3://parallelcluster-luster-ohmura deployment_type = SCRATCH_2
pcluster
コマンドでクラスター作成します。FSx for Lustreも新規作成するため通常のクラスター構築より長く20分程度かかります。コーヒー淹れて待つか、次のLustre周辺用語を予習して待ちましょう。
$ pcluster create <任意の管理名> -c <上記設定ファイル名>
Lustre関連用語の整理
これから登場する用語を説明します。
lfsコマンド
Lustre File Systemのユーティリティコマンドです。
HSM
Hierarchical Storage Management(階層型ストレージ管理) FSx for Lustreはファイルへ初回アクセス時にS3からデータを透過的に取ってきてLustreのストレージに置きます。2回目以降はLustreのストレージにあるデータは高速なアクセスが可能になっています。
lfs
コマンドのhsm_state
オプションでhsmの言葉がでてきます。
MDT・OST
- MDT(Meta Data Target)
- ファイルシステムのメタデータを保持しているストレージ
- MDS(Meta Data Server)にマウントされたストレージ領域
- OST(Object Storage Target)
- ファイルシステムの実データを保存しているストレージ
- OSS(Object Storage Server)にマウントされたストレージ領域
FSx for Lustreはマネージドサービスのため、MDS、OSSのサーバ管理も不要です。FSx for Lustreデプロイ時にストレージサイズを1.2TB単位で指定します。そこで指定したサイズはOSTのストレージサイズを指しています。
lfs
コマンドのdf
オプションの出力結果にMDT, SOTの言葉がでてきます。
OSTは図の右端のStorage Volumesにあたります。
Amazon FSx for Lustre のパフォーマンス - Amazon FSx(Lustre用)より引用
FSx for Lustre ファイルアクセスについて
完成したParallelClusterのヘッドノードにSSH接続します。S3に保存したファイルをマウントしたFSx for Lustreのディレクトリからls
コマンドで確認できます。これからアクセステストで使うデータは455MBのファイルを使います。
$ ls -lh /lustre total 1.0K -rwxr-xr-x 1 root root 13M Nov 8 01:39 s3dkq4m2.mtx.gz -rwxr-xr-x 1 root root 455M Nov 8 01:39 SEG_C3NA_Velocity.sgy
lfs hsm_state
コマンドでファイルの状態を調べることができます。出力結果のreleased
の表示はファイルが解放されており、Lustreのストレージにロードされていないことを示しています。
$ lfs hsm_state /lustre/SEG_C3NA_Velocity.sgy /lustre/SEG_C3NA_Velocity.sgy: (0x0000000d) released exists archived, archive_id:1
初回アクセス時間。16秒かかりました。(後で気づきましたHPCクラスターはus-east-1にあり、S3バケットはap-northeast-1にあります)
$ time cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fsx real 0m16.019s user 0m0.000s sys 0m0.382s
これが透過的にS3にアクセスできるの部分です。
二度目のアクセス時間。データがインスタンスにキャッシュされて早すぎるため、キャッシュ削除してもう一度。
$ time cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fsx real 0m0.244s user 0m0.000s sys 0m0.243s
キャッシュ削除後のアクセス時間。0.8秒と初回アクセスに比べると格段に早くなりました。
$ sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches' $ time cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fsx real 0m0.897s user 0m0.000s sys 0m0.416s
lfs hsm_state
コマンドでファイルの状態を再度調べます。released
の表示がなくなりました。ロードされたことがわかります。
$ time lfs hsm_state /lustre/SEG_C3NA_Velocity.sgy /lustre/SEG_C3NA_Velocity.sgy: (0x00000009) exists archived, archive_id:1 real 0m0.006s user 0m0.001s sys 0m0.000s
Lustreにロードしたファイルを解放します。ファイル自体を削除するわけではありません。
$ sudo lfs hsm_release /lustre/SEG_C3NA_Velocity.sgy
lfs hsm_state
コマンドでファイルの状態を再度調べます。released
の表示により最初の状態にもどりました。
$ time lfs hsm_state /lustre/SEG_C3NA_Velocity.sgy /lustre/SEG_C3NA_Velocity.sgy: (0x0000000d) released exists archived, archive_id:1 real 0m0.002s user 0m0.001s sys 0m0.000s
FSx for Lustre ストレージ保存容量について
lfs df
コマンドの出力結果からFSx for Lustreのストレージを見ていきます。
OST(Object Storage Target)がLustre上に保存された実データの領域です。今はなにも保存していない状態で4.5MB消費しています。
使用可能な容量が1.1TBなのはParallelCluster設定ファイルでFSx for Lustreのサイズを1.2TBに指定して作成したためです。また、MDT(Meta Data Target)の容量は約35GBで作成されています。
$ lfs df -h UUID bytes Used Available Use% Mounted on gibkbbmv-MDT0000_UUID 34.4G 5.4M 34.4G 0% /lustre[MDT:0] gibkbbmv-OST0000_UUID 1.1T 4.5M 1.1T 0% /lustre[OST:0] filesystem_summary: 1.1T 4.5M 1.1T 0% /lustre
再び455MBのサンプルファイルにアクセスします。ファイルを解放した後なので初回アクセスです。15秒かかりました。
$ time cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fs real 0m15.789s user 0m0.000s sys 0m0.451s
OSTの使用量が459MBに増えました。ファイルがLustreに載ったことがわかります。
$ lfs df -h UUID bytes Used Available Use% Mounted on gibkbbmv-MDT0000_UUID 34.4G 5.4M 34.4G 0% /lustre[MDT:0] gibkbbmv-OST0000_UUID 1.1T 459.9M 1.1T 0% /lustre[OST:0] filesystem_summary: 1.1T 459.9M 1.1T 0% /lustre
ファイルをLustreから解放して再度使用量を確認すると4.5MBに戻ります。
$ sudo lfs hsm_release /lustre/SEG_C3NA_Velocity.sgy $ lfs df -h UUID bytes Used Available Use% Mounted on gibkbbmv-MDT0000_UUID 34.4G 5.5M 34.4G 0% /lustre[MDT:0] gibkbbmv-OST0000_UUID 1.1T 4.5M 1.1T 0% /lustre[OST:0] filesystem_summary: 1.1T 4.5M 1.1T 0% /lustre
FSx for Lustre ストライピング
Amazon FSx for Lustre のパフォーマンス - Amazon FSx(Lustre用)からいくつか見ていきます。
FSx for Lustreのサイズを4.8TBで新たに作成しました。
Amazon FSx for Lustre ファイル・システムは、単一のMDTと複数のOSTで構成され、それぞれがSSDストレージ上に構築されます。各OSTのサイズは約1.17 TiBである。
lfs df
の出力結果。1.1TBのOSTが4個になり総容量が4.4TB。MDTのサイズも大きくなっています。
$ lfs df -h UUID bytes Used Available Use% Mounted on sprkbbmv-MDT0000_UUID 137.4G 6.2M 137.4G 0% /lustre[MDT:0] sprkbbmv-OST0000_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:0] sprkbbmv-OST0001_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:1] sprkbbmv-OST0002_UUID 1.1T 4.5M 1.1T 0% /lustre[OST:2] sprkbbmv-OST0003_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:3] filesystem_summary: 4.4T 18.4M 4.4T 0% /lustre
Amazon FSx for Lustreは、ファイル・システムを構成するOST全体にファイル・データを自動的に分散し、スループットとIOPS負荷でストレージ容量のバランスを取ります。
先ほどと同ようにファイルにアクセスして解放してまたアクセスすると違うOSTにファイルが保存される(動的に分散)ことが確認できました。
$ cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fs $ lfs df -h UUID bytes Used Available Use% Mounted on sprkbbmv-MDT0000_UUID 137.4G 6.4M 137.4G 0% /lustre[MDT:0] sprkbbmv-OST0000_UUID 1.1T 459.9M 1.1T 0% /lustre[OST:0] sprkbbmv-OST0001_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:1] sprkbbmv-OST0002_UUID 1.1T 4.5M 1.1T 0% /lustre[OST:2] sprkbbmv-OST0003_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:3] $ sudo lfs hsm_release /lustre/SEG_C3NA_Velocity.sgy $ cat /lustre/SEG_C3NA_Velocity.sgy > /dev/shm/fs $ lfs df -h UUID bytes Used Available Use% Mounted on sprkbbmv-MDT0000_UUID 137.4G 6.5M 137.4G 0% /lustre[MDT:0] sprkbbmv-OST0000_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:0] sprkbbmv-OST0001_UUID 1.1T 459.9M 1.1T 0% /lustre[OST:1] sprkbbmv-OST0002_UUID 1.1T 4.5M 1.1T 0% /lustre[OST:2] sprkbbmv-OST0003_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:3]
デフォルトでは、 Amazon FSx for Lustre 標準のLinuxツールを使用して、単一のディスクに格納されます。
lfs getstripe
コマンド確認するとstripe_cout
が1です。OSTが4台ありますがストライピングはされません。
$ lfs getstripe /lustre /lustre stripe_count: 1 stripe_size: 1048576 stripe_offset: -1
試しに約10GBのファイルを書き込んでみます。2分10秒かかりました。
$ time dd if=/dev/zero of=/lustre/test10g bs=20M count=500 500+0 records in 500+0 records out 10485760000 bytes (10 GB) copied, 130.572 s, 80.3 MB/s real 2m10.575s user 0m0.000s sys 0m25.407s
OST:2だけが9.8GB消費されています。デフォルトだと単一のディスクに格納されるので期待どおりの動作です。
$ lfs df -h UUID bytes Used Available Use% Mounted on sprkbbmv-MDT0000_UUID 137.4G 6.6M 137.4G 0% /lustre[MDT:0] sprkbbmv-OST0000_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:0] sprkbbmv-OST0001_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:1] sprkbbmv-OST0002_UUID 1.1T 9.8G 1.1T 1% /lustre[OST:2] sprkbbmv-OST0003_UUID 1.1T 4.6M 1.1T 0% /lustre[OST:3] filesystem_summary: 4.4T 9.8G 4.3T 0% /lustre
lfs setstripe
コマンドで速度を追い求めOST全台使ってストライピングするように設定します。
$ sudo lfs setstripe /lustre -c -1
stripe_cout
が -1 になりました。OST全台を使うことを意味します。
$ lfs getstripe /lustre /lustre stripe_count: -1 stripe_size: 1048576 stripe_offset: -1
先ほどのファイル削除しました。再度10GBのファイルを書き込みます。ストライピングにより34秒で書き込みが終わりました。
$ time dd if=/dev/zero of=/lustre/test10g bs=10M count=1000 1000+0 records in 1000+0 records out 10485760000 bytes (10 GB) copied, 34.0756 s, 308 MB/s real 0m34.078s user 0m0.000s sys 0m21.862s
各OSTに2.4GBずつ分散して保存されています。書き込み時間も2分10秒から34秒と4分の1程度でした。
$ lfs df -h UUID bytes Used Available Use% Mounted on sprkbbmv-MDT0000_UUID 137.4G 6.6M 137.4G 0% /lustre[MDT:0] sprkbbmv-OST0000_UUID 1.1T 2.4G 1.1T 0% /lustre[OST:0] sprkbbmv-OST0001_UUID 1.1T 2.4G 1.1T 0% /lustre[OST:1] sprkbbmv-OST0002_UUID 1.1T 2.4G 1.1T 0% /lustre[OST:2] sprkbbmv-OST0003_UUID 1.1T 2.4G 1.1T 0% /lustre[OST:3] filesystem_summary: 4.4T 9.8G 4.3T 0% /lustre
FSx for LustreからS3へ保存します。ずいぶん遅いなと思ったらHPCクラスターはus-east-1で作成し、S3バケットがap-northeast-1でした。
- lfs hsm_archive
- S3バケットへエクスポートします。
- lfs hsm_action
- S3へエクスポートされたか進捗・完了確認できます。
NOOP
が表示されれば正常にエクスポート完了です。
$ sudo lfs hsm_archive /lustre/test10g $ sudo lfs hsm_action /lustre/test10g /lustre/test10g: ARCHIVE running (0 bytes moved) $ sudo lfs hsm_action /lustre/test10g /lustre/test10g: ARCHIVE running (5578424320 bytes moved) $ sudo lfs hsm_action /lustre/test10g /lustre/test10g: NOOP
NOOP表示を確認後、S3バケットを確認しました。test10gファイルが保存されていました。
S3から初期インポートされたファイル
初期インポートされたファイルはlmm_stripe_count
が1になっており。OSTが複数台あってもストライピングされません。動的分散のときに確認しましたが保存されるOSTの単位で変わるだけでファイルがOSTにまたがって分散して保存はされませんでした。
$ lfs getstripe /lustre/SEG_C3NA_Velocity.sgy /lustre/SEG_C3NA_Velocity.sgy lmm_stripe_count: 1 lmm_stripe_size: 1048576 lmm_pattern: 1 lmm_layout_gen: 13 lmm_stripe_offset: 1 obdidx objid objid group 1 8 0x8 0
変更できるか試したのですが上手くいかず。OSTが複数台ある場合はストライピングの設定してからS3インポートした方が楽なのではない思い深追いしませんでした。
$ sudo lfs setstripe /lustre/SEG_C3NA_Velocity.sgy -c -1 error on ioctl 0x4008669a for '/lustre/SEG_C3NA_Velocity.sgy' (3): stripe already set error: setstripe: create striped file '/lustre/SEG_C3NA_Velocity.sgy' failed: File exists
おわりに
AWS HPC WorkShopsに沿ってすすめるつもりだったのですがLustreの奥が深くあれこれ試したら脱線しました。AWSでマネージドのLustreを動かすというところではS3を透過的に利用できるのが便利でした。ワークショップズはI/Oのベンチマークをやっているので次回試したいです。
参考
Lustreについて
20170905.pdf
Ubuntu Manpage: lfs - Lustre utility to create a file with specific striping pattern, find the striping
I/O and Lustre Usage | National Institute for Computational Sciences
Configuring Lustre File Striping - Lustre Wiki